package com.palm.easy.detector;

import com.sun.management.OperatingSystemMXBean;
import org.noear.solon.extend.health.detector.AbstractDetector;

import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

public class ProcessDetector extends AbstractDetector {
    private static final Pattern wmicPattern = Pattern.compile("(.*)\\s+([\\d]+)\\s+([\\d]+)", 42);
    private long pid;

    public ProcessDetector(long pid) {
        this.pid = pid;
    }

    @Override
    public String getName() {
        return "process";
    }

    @Override
    public Map<String, Object> getInfo() {
        Map<String, Object> info = new HashMap<>();
        if (pid <= 0) {
            return info;
        }
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        long totalMemory = osmxb.getTotalPhysicalMemorySize();
        info.put("TotalMemory", totalMemory);

        if (osName.indexOf("windows") > -1) {
            try {
                String mem = execute("tasklist", "/FI", "\"PID eq " + pid + "\"");
                String[] lines = mem.split("\n");
                if (lines.length > 3) {
                    String[] values = lines[3].split("\\s+");
                    long memUse = Long.valueOf(values[4].replaceAll(",","")) * 1024;
                    info.put("RSS", memUse);
                    info.put("MEM", new DecimalFormat("##.00").format(memUse * 100f / totalMemory));
                }
                readCpuRatioForWindows(info,pid);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            try {
                String result = execute("ps", "u", "-p", pid + "");
                String[] lines = result.split("\n");

                if (lines.length > 1) {
                    String[] values = lines[1].split("\\s+");
                    info.put("CPU", values[2]);
                    info.put("MEM", values[3]);
                    info.put("RSS", values[4]);//内存使用量
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return info;
    }
    private long[] readCpuTime(String text) throws Exception {
        long[] retn = null;
        List<String[]> lines = matcher(wmicPattern, text);
        long idletime = 0L;
        long kneltime = 0L;
        long usertime = 0L;
        for (String[] line : lines) {

            String caption = line[1];
            long kernelModeTime = Long.valueOf(line[2]);
            long userModeTime = Long.valueOf(line[3]);
            if (caption.indexOf("WMIC.exe") >= 0) {
                continue;
            }
            if (caption.equals("System Idle Process") || caption.equals("System")) {
                idletime += kernelModeTime;
                idletime += userModeTime;
                continue;
            }
            kneltime += kernelModeTime;
            usertime += userModeTime;
        }
        retn = new long[2];
        retn[0] = idletime;
        retn[1] = kneltime + usertime;
        return retn;
    }

    private void readCpuRatioForWindows(Map<String,Object> detectorInfo,long pid) throws Exception {
        String[] cmd = { "wmic", "process","where","\"Caption='System' or Caption='System Idle Process' or ProcessId="+pid+"\"", "get", "Caption,KernelModeTime,UserModeTime" };

        long[] c0 = readCpuTime(execute(cmd));
        Thread.sleep(30L);
        long[] c1 = readCpuTime(execute(cmd));
        if (c0 != null && c1 != null) {
            long idletime = c1[0] - c0[0];
            long busytime = c1[1] - c0[1];
            float cpu= (float)busytime * 100.0F / (float)(busytime + idletime);
            detectorInfo.put("CPU",new DecimalFormat("##.00").format(cpu));
        }
    }
    /**
     * ps u -p 60901
     * USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
     * root       60901  0.2  4.7 10040112 748964 ?     Sl   12月01  22:35 java -jar -Dname=arg-admin.jar -Duser.timezone=Asia/Shanghai -XX:+HeapDumpOnOutOfMemoryError -Dspring.
     */
    /**
     * wmic process  where ProcessId=7516  get KernelModeTime,UserModeTime
     * KernelModeTime  UserModeTime
     * 262656250       0
     */
    /**
     * wmic process  where "Caption='System' or Caption='System Idle Process'"  get Caption,KernelModeTime,UserModeTime
     * Caption              KernelModeTime  UserModeTime
     * System Idle Process  261528750000    0
     * System               5102500000      0
     */
    /**
     * tasklist /FI "PID eq 4"
     * 映像名称                       PID 会话名              会话#       内存使用
     * ========================= ======== ================ =========== ============
     * System                           4 Services                   0        128 K
     **/


}
